package org.franca.importer.ea.post;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.franca.core.franca.FEnumerationType;
import org.franca.core.franca.FModel;
import org.franca.core.franca.FStructType;
import org.franca.core.franca.FUnionType;
import org.franca.importer.ea.utils.EAConstants;
import org.franca.importer.ea.utils.EARepositoryAccessor;
import org.sparx.Attribute;
import org.sparx.Diagram;
import org.sparx.DiagramObject;
import org.sparx.Element;
import org.sparx.Package;

public class TypeDiagramCreator extends PostProcessorDecorator {

	public TypeDiagramCreator(PostProcessor lProcessor) {
		super(lProcessor);
	}

	@Override
	public void doConsistencyCheckForStructure(Element eaStruct,
			FStructType fStruct) {

		processor.doConsistencyCheckForStructure(eaStruct, fStruct);
	}

	@Override
	public void doConsistencyCheckForEnumeration(Element eaEnum,
			FEnumerationType fEnum) {

		processor.doConsistencyCheckForEnumeration(eaEnum, fEnum);
	}

	@Override
	public void doConsistencyCheckForPackage(Package eaPackage, FModel fModel) {

		processor.doConsistencyCheckForPackage(eaPackage, fModel);				
		
		// Delete the diagram if already exists
		for(short i=0; i<eaPackage.GetDiagrams().GetCount(); i++) {
			Diagram d = eaPackage.GetDiagrams().GetAt(i);
			if(d.GetName().equals("Type Overview")) {
				eaPackage.GetDiagrams().Delete(i);
			}
		}
		eaPackage.GetDiagrams().Refresh();
		
		HashSet<Integer> localElements = new HashSet<Integer>();
		
		Diagram diagram = eaPackage.GetDiagrams().AddNew("Type Overview", "Logical");
		diagram.Update();

		// Collect all local elements
		for(Element e: eaPackage.GetElements()) {						
			localElements.add(e.GetElementID());
			DiagramObject dObj = diagram.GetDiagramObjects().AddNew("", "");
			dObj.SetElementID(e.GetElementID());
			dObj.SetDiagramID(diagram.GetDiagramID());
			dObj.Update();
		}
		
		// Collect all referenced elements
		if(EAConstants.DIAGRAM_SHOW_EXTERNAL_DEPENDENCIES.equals("true")) {
			for(Element e: eaPackage.GetElements()) {						
				for(Attribute a: e.GetAttributes()) {
					Element refElem = EARepositoryAccessor.INSTANCE.findElement(a.GetType());
					if(refElem != null) {
						if(!localElements.contains(refElem.GetElementID())) {
							localElements.add(refElem.GetElementID());					
							DiagramObject dObj = diagram.GetDiagramObjects().AddNew("", "");
							dObj.SetElementID(refElem.GetElementID());
							dObj.SetDiagramID(diagram.GetDiagramID());
							int bColor = Integer.parseInt(EAConstants.DIAGRAM_EXTERNAL_DEPENDENCIES_BACKGROUND, 16);
							dObj.SetStyle("BCol="+bColor);
							dObj.Update();							
						}
					}
				}							
			}
		}
		
				
		// add all elements to the diagram
//		Iterator<Integer> it = localElements.iterator();
//		while(it.hasNext()) {
//			DiagramObject dObj = diagram.GetDiagramObjects().AddNew("", "");
//			dObj.SetElementID(it.next().intValue());
//			dObj.SetDiagramID(diagram.GetDiagramID());
//			dObj.Update();
//		}
		localElements.clear();		
		
		diagram.SetOrientation("P");
		diagram.Update();
		
		EARepositoryAccessor.INSTANCE.layoutDiagram(diagram);
		
		eaPackage.GetDiagrams().Refresh();
				
	}

	@Override
	public void doConsistencyCheckForUnion(Element eaStruct,
			FUnionType fUnion) {

		processor.doConsistencyCheckForUnion(eaStruct, fUnion);
	}
	
}
